package com.liuyang.demo.excel.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Description:读取excel工具类
 */

public class ExcelReaderUtil {

    private static final int version2003 = 2003;

    private static final int version2007 = 2007;

    private static int version = version2003;

    private static Workbook wb = null;
    private static Sheet sheet = null;
    private static Row row = null;

    private ExcelReaderUtil() {
    }

    /**
     * Description: 读取Excel表格表头的内容
     *
     * @param wb 工作薄
     * @return String 表头内容的数组
     * @Author
     * @Create Date: 2014-4-22 下午12:01:32
     */
    public static String[] readExcelTitle(Workbook wb) {
        sheet = wb.getSheetAt(0);
        row = sheet.getRow(0);
        // 标题总列数
        int colNum = row.getPhysicalNumberOfCells();
        String[] title = new String[colNum];
        for (int i = 0; i < colNum; i++) {
            title[i] = getCellFormatValue(row.getCell((short) i));
        }
        return title;
    }

    public static void setCellTypeString(Workbook wb) {
        sheet = wb.getSheetAt(0);
        int rowNum = sheet.getLastRowNum();
        row = sheet.getRow(0);
        int colNum = row != null ? row.getPhysicalNumberOfCells() : 0;
        for (int i = 0; i <= rowNum; i++) {
            row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            //如果Excel第一行的列数大于0，则列数以第一行为准，否则每循环一行取当前行列数作为colnum
            colNum = colNum > 0 ? colNum : (row != null ? row.getPhysicalNumberOfCells() : 0);
            // 计数器countNull，记录整行是否为空，如果整行为空的时候，不放到集合里
            int j = 0;
            while (j < colNum) {
                Cell cell = row.getCell((short) j);
                if (cell != null) {
                    boolean isDate = (cell.getCellType() == Cell.CELL_TYPE_NUMERIC || cell.getCellType() == Cell.CELL_TYPE_FORMULA) && HSSFDateUtil.isCellDateFormatted(cell);
                    if (!isDate) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                    }
                }
                j++;
            }
        }
    }

    /**
     * Description: 读取Excel正文内容
     *
     * @param wb
     * @return 每一行数据为一个List<String> ,所有行为 LinkedList<List<String>>
     * @Author
     * @Create Date: 2014-4-22 上午11:58:36
     */
    public static LinkedList<List<String>> readExcelContent(Workbook wb) {
        return readExcelContent(wb, true, 2);
    }

    /**
     * @param wb
     * @param startLine
     * @return
     */
    public static LinkedList<List<String>> readExcelContent(Workbook wb, Integer startLine) {
        return readExcelContent(wb, true, startLine);
    }

    /**
     * Description: 读取Excel正文内容
     *
     * @param wb
     * @param blankLineFlag 是否处理空行, true处理,false不处理
     * @return 每一行数据为一个List<String> ,所有行为 LinkedList<List<String>>
     * @Author
     * @Create Date: 2014-4-22 上午11:58:36
     */
    public static LinkedList<List<String>> readExcelContent(Workbook wb, Boolean blankLineFlag, Integer startLine) {
        LinkedList<List<String>> list = new LinkedList<List<String>>();

        List<String> contentList = null;
        String str = "";
        sheet = wb.getSheetAt(0);
        // 得到总行数
        int rowNum = sheet.getLastRowNum();
        // 得到第一行数据
        row = sheet.getRow(0);
        // 得到Excel第一行的列数
        int colNum = row != null ? row.getPhysicalNumberOfCells() : 0;
        // 正文内容应该从第二行开始,第一行为表头的标题
        for (int i = startLine - 1; i <= rowNum; i++) {
            contentList = new ArrayList<String>();
            row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            //如果Excel第一行的列数大于0，则列数以第一行为准，否则每循环一行取当前行列数作为colnum
            colNum = colNum > 0 ? colNum : (row != null ? row.getPhysicalNumberOfCells() : 0);
            // 计数器countNull，记录整行是否为空，如果整行为空的时候，不放到集合里
            int countNull = 0;
            int j = 0;
            while (j < colNum) {
                str = getCellFormatValue(row.getCell((short) j)).trim();
                if (StringUtils.isEmpty(str)) {
                    ++countNull;
                }
                if (str.endsWith(".0")) {
                    str = str.substring(0, str.lastIndexOf(".0"));
                }
                j++;
                contentList.add(str);
            }
            if (blankLineFlag && colNum == countNull) {
                continue;
            }
            list.add(contentList);
        }
        return list;
    }

    /**
     * Description: 获取单元格数据内容为字符串类型的数据
     *
     * @param cell2 Excel单元格
     * @return 单元格数据内容
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:27:13
     */
    private static String getStringCellValue(Cell cell2) {
        String strCell = "";
        switch (cell2.getCellType()) {
            case HSSFCell.CELL_TYPE_STRING:
                strCell = cell2.getStringCellValue();
                break;
            case HSSFCell.CELL_TYPE_NUMERIC:
                strCell = String.valueOf(cell2.getNumericCellValue());
                break;
            case HSSFCell.CELL_TYPE_BOOLEAN:
                strCell = String.valueOf(cell2.getBooleanCellValue());
                break;
            case HSSFCell.CELL_TYPE_BLANK:
                strCell = "";
                break;
            default:
                strCell = "";
                break;
        }
        if (strCell.equals("") || strCell == null) {
            return "";
        }
        return strCell;
    }

    /**
     * Description: 获取单元格数据内容为日期类型的数据
     *
     * @param cell2 Excel单元格
     * @return
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:26:41
     */
    @SuppressWarnings("deprecation")
    private static String getDateCellValue(Cell cell2) {
        String result = "";
        try {
            int cellType = cell2.getCellType();
            if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
                Date date = cell2.getDateCellValue();
                result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1) + "-" + date.getDate();
            } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
                String date = getStringCellValue(cell2);
                result = date.replaceAll("[年月]", "-").replace("日", "").trim();
            } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
                result = "";
            }
        } catch (Exception e) {
            System.out.println("日期格式不正确!");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Description: 根据HSSFCell类型设置数据
     *
     * @param cell
     * @return
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:26:22
     */
    private static String getCellFormatValue(Cell cell) {
        String cellvalue = "";
        if (cell != null) {
            // 判断当前Cell的Type
            switch (cell.getCellType()) {
                // 如果当前Cell的Type为NUMERIC
                case HSSFCell.CELL_TYPE_NUMERIC:
                case HSSFCell.CELL_TYPE_FORMULA: {
                    // 判断当前的cell是否为Date
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
                        // 如果是Date类型则，转化为Data格式
                        cellvalue = getDateCellValue(cell);
                    }
                    // 如果是纯数字
                    else {
                        // 取得当前Cell的数值
                        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                        cellvalue = cell.getStringCellValue();
                    }
                    break;
                }
                // 如果当前Cell的Type为STRIN
                case HSSFCell.CELL_TYPE_STRING:
                    // 取得当前的Cell字符串
                    cellvalue = cell.getRichStringCellValue().getString();
                    break;
                // 默认的Cell值
                default:
                    cellvalue = " ";
            }
        } else {
            cellvalue = "";
        }
        return cellvalue;
    }

    /**
     * Description: 获得工作簿
     *
     * @param excelFilePath Excel文件全路径
     * @return
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:21:54
     */
    public static Workbook getWorkbook(String excelFilePath) {
        return initWorkbook(excelFilePath, null);
    }

    /**
     * Description: 获得工作簿
     *
     * @param fileName Excel文件名称
     * @param stream   Excel文件输入流
     * @return
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:22:14
     */
    public static Workbook getWorkbook(String fileName, InputStream stream) {
        return initWorkbook(fileName, stream);
    }

    /**
     * Description: 初始化工作簿
     *
     * @param str    Excel名称或者文件全路径
     * @param stream Excel文件输入流
     * @return
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:22:48
     */
    private static Workbook initWorkbook(String str, InputStream stream) {
        try {
            if (str.endsWith(".xls")) {
                version = version2003;
            } else if (str.endsWith(".xlsx")) {
                version = version2007;
            }
            if (null == stream) {
                stream = new FileInputStream(str);
            }
            if (version == version2003) {
                wb = (HSSFWorkbook) new HSSFWorkbook(stream);
            } else if (version == version2007) {
                //会自动关闭流
                wb = WorkbookFactory.create(stream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeStream(stream);
        }
        return wb;
    }

    /**
     * Description: 关闭流
     *
     * @param stream
     * @Author wangheng
     * @Create Date: 2014年10月22日 下午1:24:05
     */
    private static void closeStream(InputStream stream) {
        try {
            if (null != stream) {
                stream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        try {
            // 对读取Excel表格标题测试
            Workbook is = getWorkbook("C:\\Users\\miao\\Desktop\\table.xls");

//			String[] title = readExcelTitle(is);
//			System.out.println("获得Excel表格的标题:");
//			for (String s : title) {
//				System.out.println(s + " ");
//			}

            // 对读取Excel表格内容测试
            System.out.println("获得Excel表格的内容:");
            List<List<String>> lisp = readExcelContent(is,true,1);
            for (int i = 0; i < lisp.size(); i++) {
                System.out.println(i + "--" + lisp.get(i));
                System.out.println(lisp.get(i).get(0) + "--" + lisp.get(i).get(1));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**  controller中运用:
     MultipartFile mf = multipartFiles[0];
     InputStream in = mf.getInputStream();
     Workbook workbook = ExcelReaderUtil.getWorkbook(mf.getOriginalFilename(), in);
     List<List<String>> lisp = ExcelReaderUtil.readExcelContent(workbook);

     */

}
